package com.xbongbong.paas.script.controller;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.PaasFormExplainEntity;
import com.xbongbong.paas.domain.entity.PaasMenuEntity;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.enums.MenuTypeEnum;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.help.menu.InitJxcMenuHelp;
import com.xbongbong.paas.model.PaasFormExplainModel;
import com.xbongbong.paas.model.PaasMenuModel;
import com.xbongbong.paas.pojo.dto.FixDataJobDTO;
import com.xbongbong.paas.pojo.dto.FormEntityAddDTO;
import com.xbongbong.paas.service.PaasFormService;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.Arith;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.paas.toolbox.wrap.BaseDTO;
import com.xbongbong.paas.util.ExplainUtil;
import com.xbongbong.pro.config.ProBaseConfig;
import com.xbongbong.pro.constant.XbbProConstant;
import com.xbongbong.pro.domain.entity.UpdateDataEntity;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.enums.menu.enums.AccordConfigMenuEnum;
import com.xbongbong.pro.form.pojo.dto.FormAddBatchDTO;
import com.xbongbong.pro.form.pojo.vo.FormAddBatchVO;
import com.xbongbong.pro.menu.pojo.dto.MenuInitDTO;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.ParameterConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.domain.dao.ProductStockDao;
import com.xbongbong.saas.domain.entity.ProductStockEntity;
import com.xbongbong.saas.domain.entity.ext.ProductEntityExt;
import com.xbongbong.saas.enums.CompanyConfigEnum;
import com.xbongbong.saas.enums.SelectProductEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.AssembleEnum;
import com.xbongbong.saas.enums.business.OriStockEnum;
import com.xbongbong.saas.enums.business.ProductEnum;
import com.xbongbong.saas.enums.product.AssembleInProductEnum;
import com.xbongbong.saas.enums.product.AssembleProductEnum;
import com.xbongbong.saas.enums.product.ContractOutstockProductEnum;
import com.xbongbong.saas.enums.product.InstockProductEnum;
import com.xbongbong.saas.enums.product.OriStockProductEnum;
import com.xbongbong.saas.enums.product.OutstockProductEnum;
import com.xbongbong.saas.enums.product.ProductionInstockProductEnum;
import com.xbongbong.saas.enums.product.ProductionMaterielOutstockProductEnum;
import com.xbongbong.saas.enums.product.PurchaseInstockProductEnum;
import com.xbongbong.saas.enums.product.ReturnedMaterielInstockProductEnum;
import com.xbongbong.saas.enums.product.ReturnedPurchaseOutstockProductEnum;
import com.xbongbong.saas.enums.product.WorkOrderOutstockProductEnum;
import com.xbongbong.saas.model.ProductModel;
import com.xbongbong.saas.model.ProductStockModel;
import com.xbongbong.saas.script.help.InitExplainsHelper;
import com.xbongbong.saas.script.tempenum.TempProductEnum;
import com.xbongbong.saas.script.tempenum.product.TempAssembleInProductEnum;
import com.xbongbong.saas.script.tempenum.product.TempAssembleProductEnum;
import com.xbongbong.saas.script.tempenum.product.TempContractOutstockProductEnum;
import com.xbongbong.saas.script.tempenum.product.TempInstockProductEnum;
import com.xbongbong.saas.script.tempenum.product.TempOriStockProductEnum;
import com.xbongbong.saas.script.tempenum.product.TempOutstockProductEnum;
import com.xbongbong.saas.script.tempenum.product.TempProductionInstockProductEnum;
import com.xbongbong.saas.script.tempenum.product.TempProductionMaterielOutstockProductEnum;
import com.xbongbong.saas.script.tempenum.product.TempPurchaseInstockProductEnum;
import com.xbongbong.saas.script.tempenum.product.TempReturnedMaterielInstockProductEnum;
import com.xbongbong.saas.script.tempenum.product.TempReturnedPurchaseOutstockProductEnum;
import com.xbongbong.saas.script.tempenum.product.TempWorkOrderOutstockProductEnum;
import com.xbongbong.saas.service.BatchFlowBillService;
import com.xbongbong.sys.domain.entity.CompanyConfigEntity;
import com.xbongbong.sys.model.CompanyConfigModel;
import com.xbongbong.sys.model.CompanyModel;
import org.apache.commons.collections4.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.http.MediaType;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

/**
 * @author feng.zheng
 * @version v1.0
 * @date 2019/10/12 15:15
 * @since v1.0
 */
@RestController
@RequestMapping(XbbProConstant.API_ROOT_PREFIX + "/script/batch/seq")
public class BatchSeqScriptController {
    private static final Logger LOG = LoggerFactory.getLogger(BatchSeqScriptController.class);
    @Resource
    private ProBaseConfig proBaseConfig;
    @Resource
    private ProductModel productModel;
    @Resource
    private ProductStockModel productStockModel;
    @Resource
    private CompanyConfigModel companyConfigModel;
    @Resource
    private CompanyModel companyModel;
    @Resource
    private PaasFormExplainModel paasFormExplainModel;
    @Resource
    private PaasMenuModel paasMenuModel;
    @Resource
    private InitJxcMenuHelp initJxcMenuHelp;
    @Resource
    private PaasFormService paasFormService;
    @Resource
    private ProductStockDao productStockDao;
    @Resource
    private BatchFlowBillService batchFlowBillService;

    /**
     * 老批次数据处理
     *
     * @param fixDataJobDTO 入参
     * @param br            校验
     * @return 成功
     * @throws Exception 异常
     */
    @Deprecated
    @RequestMapping(value = "/oldBatchHandle", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String oldBatchHandle(@RequestBody @Valid FixDataJobDTO fixDataJobDTO, BindingResult br) throws Exception {
        if (!proBaseConfig.getXbbCode().equals(fixDataJobDTO.getXbbCode())) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100006, SystemErrorCodeEnum.API_ERROR_100006.getMsg());
        }
        long start = DateTimeUtil.getInt();
        long today = DateTimeUtil.getTodayInt();
        List<String> corpidList = fixDataJobDTO.getCorpidList();
        if (CollectionsUtil.isEmpty(corpidList)) {
            corpidList = productModel.getCorpidList();
        }
        LOG.warn("数据库中共有产品公司" + corpidList.size() + "家");
        int corpidCount = 0;
        StringBuilder stringBuilder;
        for (String corpid : corpidList) {
            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put(ParameterConstant.DEL, DelEnum.NORMAL.getDel());
            param.put(ParameterConstant.CORPID, corpid);
            param.put("orderByStr", "id");
            param.put("pageSize", 1500);
            boolean flag = true;
            Map<String, List<ProductStockEntity>> batchKeyMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            List<ProductStockEntity> oneCompanyProductStockList = new ArrayList<>();
            while (flag) {
                List<ProductStockEntity> productStockEntityList = productStockModel.getHasBatchStockList(param);
                if (Objects.isNull(productStockEntityList) || productStockEntityList.isEmpty()) {
                    flag = false;
                } else {
                    LOG.warn("遍历id到" + productStockEntityList.get(productStockEntityList.size() - 1).getId());
                    param.put("idGte", productStockEntityList.get(productStockEntityList.size() - 1).getId());
                    Iterator<ProductStockEntity> iterator = productStockEntityList.iterator();
                    while (iterator.hasNext()) {
                        ProductStockEntity productStockEntity = iterator.next();
                        stringBuilder = new StringBuilder();
                        if (StringUtil.isEmpty(productStockEntity.getBatch())) {
                            productStockEntity.setBatch("空");
                        }
                        if (Objects.isNull(productStockEntity.getProduceDate()) || Objects.equals(productStockEntity.getProduceDate(), 0L)) {
                            if (Objects.isNull(productStockEntity.getProduceDate())) {
                                productStockEntity.setProduceDate(0L);
                            }
                            if (Objects.nonNull(productStockEntity.getGuaranteePeriod()) && !Objects.equals(productStockEntity.getGuaranteePeriod(), 0L)) {
                                productStockEntity.setProduceDate(today - productStockEntity.getGuaranteePeriod());
                            }
                        }
                        if (Objects.isNull(productStockEntity.getGuaranteePeriod())) {
                            productStockEntity.setGuaranteePeriod(0L);
                        }
                        StringUtil.stringBuilderAppendSuffix(stringBuilder, StringConstant.CROSS, productStockEntity.getProductId(), productStockEntity.getWarehouseId(), productStockEntity.getBatch(), productStockEntity.getProduceDate(), productStockEntity.getGuaranteePeriod());
                        productStockEntity.setBatchKey(stringBuilder.toString());
                        productStockEntity.setExpireDate(productStockEntity.getProduceDate() + productStockEntity.getGuaranteePeriod());
                        List<ProductStockEntity> batchKeyStockEntities = batchKeyMap.getOrDefault(productStockEntity.getBatchKey(), new ArrayList<>());
                        batchKeyStockEntities.add(productStockEntity);
                        batchKeyMap.put(productStockEntity.getBatchKey(), batchKeyStockEntities);
                        oneCompanyProductStockList.add(productStockEntity);
                    }
                }
            }
            Map<Long, ProductStockEntity> needMergeStockMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            for (Map.Entry<String, List<ProductStockEntity>> entry : batchKeyMap.entrySet()) {
                if (entry.getValue().size() > 1) {
                    double sumNum = 0D;
                    double sumCost = 0D;
                    for (ProductStockEntity productStockEntity : entry.getValue()) {
                        sumNum = Arith.add(sumNum, productStockEntity.getNum());
                        sumCost = Arith.add(sumCost, Arith.mul(productStockEntity.getNum(), productStockEntity.getCost()));
                    }
                    for (int i = 0; i < entry.getValue().size(); i++) {
                        ProductStockEntity productStockEntity = entry.getValue().get(i);
                        if (i == 0) {
                            productStockEntity.setNum(sumNum);
                            productStockEntity.setCost(Arith.div(sumCost, sumNum));
                        } else {
                            productStockEntity.setDel(DelEnum.DELETE.getDel());
                        }
                        needMergeStockMap.put(productStockEntity.getId(), productStockEntity);
                    }
                }
            }
            for (ProductStockEntity productStockEntity : oneCompanyProductStockList) {
                if (needMergeStockMap.containsKey(productStockEntity.getId())) {
                    productStockEntity = needMergeStockMap.get(productStockEntity.getId());
                }
            }
            if (CollectionsUtil.isNotEmpty(oneCompanyProductStockList)) {
                int insertTotal = oneCompanyProductStockList.size();
                int insertPageSize = 1000;
                int insertTotalPage = (insertTotal % insertPageSize == 0) ? (insertTotal / insertPageSize) : (insertTotal / insertPageSize) + 1;
                for (int page = 0; page < insertTotalPage; page++) {
                    List<ProductStockEntity> updateList;
                    if (page == insertTotalPage - 1) {
                        updateList = oneCompanyProductStockList.subList(insertPageSize * page, oneCompanyProductStockList.size());
                    } else {
                        updateList = oneCompanyProductStockList.subList(insertPageSize * page, insertPageSize * (page + 1));
                    }
                    productStockDao.updateBatch(updateList, corpid);
                }
            }
            ++corpidCount;
            LOG.warn("公司" + corpidCount + "/" + corpidList.size());
        }
        LOG.warn("consume:" + (DateTimeUtil.getInt() - start));
        LOG.warn("操作成功");
        return "success";
    }


    /**
     * 老公司公司级配置批次保质期配置开关及批次流水菜单生成
     *
     * @param fixDataJobDTO 入参
     * @param br            校验
     * @return 成功
     * @throws Exception 异常
     */
    @RequestMapping(value = "/batchShelfConfig", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String batchShelfConfig(@RequestBody @Valid FixDataJobDTO fixDataJobDTO, BindingResult br) throws Exception {
        if (!proBaseConfig.getXbbCode().equals(fixDataJobDTO.getXbbCode())) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100006, SystemErrorCodeEnum.API_ERROR_100006.getMsg());
        }
        long start = DateTimeUtil.getInt();
        LocaleContextHolder.setLocale(Locale.CHINA);
        List<String> corpidList = fixDataJobDTO.getCorpidList();
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put(ParameterConstant.DEL, DelEnum.NORMAL.getDel());
        param.put("configAliasIn", Arrays.asList(CompanyConfigEnum.ENABLE_BATCH_SHELF_MANAGEMENT.getAlias(), CompanyConfigEnum.ENABLE_STOCK_FLOW_BILL.getAlias()));
        if (CollectionsUtil.isEmpty(corpidList)) {
            corpidList = productModel.getCorpidList();
        } else {
            param.put("corpidList", corpidList);
        }
        param.put("noLimit", 1);
        LOG.warn("数据库中共有产品公司" + corpidList.size() + "家");
        List<CompanyConfigEntity> batchConfigList = companyConfigModel.findEntitys(param);
        Map<String, CompanyConfigEntity> batchConfigMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<String, Boolean> flowEnableConfigMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        batchConfigList.forEach(config -> {
            if (Objects.equals(config.getConfigAlias(), CompanyConfigEnum.ENABLE_BATCH_SHELF_MANAGEMENT.getAlias())) {
                batchConfigMap.put(config.getCorpid(), config);
            } else {
                flowEnableConfigMap.put(config.getCorpid(), BasicConstant.IS_USE.toString().equals(config.getConfigValue()));
            }
        });
        List<CompanyConfigEntity> updateConfigList = new ArrayList<>();
        List<CompanyConfigEntity> addConfigList = new ArrayList<>();
        List<String> existBatchCorpidList = productStockModel.getCorpidExistBatch(corpidList);
        LOG.warn("存在批次的公司数 " + existBatchCorpidList.size());
        for (String corpid : existBatchCorpidList) {
            if (batchConfigMap.containsKey(corpid)) {
                CompanyConfigEntity companyConfigEntity = batchConfigMap.get(corpid);
                if (!Objects.equals(companyConfigEntity.getConfigValue(), BasicConstant.IS_USE.toString())) {
                    companyConfigEntity.setConfigValue(BasicConstant.IS_USE.toString());
                    updateConfigList.add(companyConfigEntity);
                }
            } else {
                CompanyConfigEntity companyConfigEntity = new CompanyConfigEntity(corpid, CompanyConfigEnum.ENABLE_BATCH_SHELF_MANAGEMENT.getName(), CompanyConfigEnum.ENABLE_BATCH_SHELF_MANAGEMENT.getAlias(), BasicConstant.IS_USE.toString());
                addConfigList.add(companyConfigEntity);
            }
        }
        Map<String, Object> menuParam = new HashMap<>();
        menuParam.put(ParameterConstant.DEL, DelEnum.NORMAL.getDel());
        menuParam.put("corpidIn", existBatchCorpidList);
        menuParam.put("aliasIn", Arrays.asList(XbbRefTypeEnum.BATCH_FLOW_BILL.getAlias(), XbbRefTypeEnum.INVENTORY_MANAGEMENT.getAlias()));
        List<PaasMenuEntity> menuEntities = paasMenuModel.findEntitys(menuParam);
        List<String> hasBatchFlowCompanyList = new ArrayList<>();
        menuEntities.forEach(menu -> {
            if (Objects.equals(menu.getAlias(), XbbRefTypeEnum.BATCH_FLOW_BILL.getAlias())) {
                hasBatchFlowCompanyList.add(menu.getCorpid());
            }
        });
        List<PaasMenuEntity> formAddMenuList = new ArrayList<>();
        PaasMenuEntity paasMenuEntity;
        LOG.warn("需要插入的菜单数 " + menuEntities.size());
        List<String> hasFlowCompanyList = new ArrayList<>();
        for (int j = 0; j < menuEntities.size(); j++) {
            PaasMenuEntity item = menuEntities.get(j);
            if (hasBatchFlowCompanyList.contains(item.getCorpid())) {
                continue;
            }
            paasMenuEntity = new PaasMenuEntity();
            paasMenuEntity.setCorpid(item.getCorpid());
            paasMenuEntity.setAppId(item.getAppId());
            paasMenuEntity.setParentId(item.getId());
            // 老公司可能库存流水菜单还未生成，随便给个排序，与马雄商量了，用户自行调整
            paasMenuEntity.setSort(7);
            paasMenuEntity.setCreatorId(item.getCreatorId());
            paasMenuEntity.setAlias(AccordConfigMenuEnum.BATCH_FLOW_BILL.getAlias());
            paasMenuEntity.setColor(AccordConfigMenuEnum.BATCH_FLOW_BILL.getAccessLinkEnum().getColor());
            paasMenuEntity.setIcon(AccordConfigMenuEnum.BATCH_FLOW_BILL.getAccessLinkEnum().getIcon());
            paasMenuEntity.setSaasMark(SaasMarkEnum.SAAS.getCode());
            paasMenuEntity.setUrl(AccordConfigMenuEnum.BATCH_FLOW_BILL.getAccessLinkEnum().getUrl());
            paasMenuEntity.setMobileUrl(AccordConfigMenuEnum.BATCH_FLOW_BILL.getAccessLinkEnum().getMobileUrl());
            paasMenuEntity.setType(MenuTypeEnum.FORM.getType());
            paasMenuEntity.setEnable(0);
            if (flowEnableConfigMap.getOrDefault(item.getCorpid(), false)) {
                hasFlowCompanyList.add(item.getCorpid());
                paasMenuEntity.setEnable(1);
            }
            paasMenuEntity.setName(AccordConfigMenuEnum.BATCH_FLOW_BILL.getName());
            paasMenuEntity.setAddTime(start);
            paasMenuEntity.setUpdateTime(start);
            formAddMenuList.add(paasMenuEntity);
        }
        if (CollectionUtils.isEmpty(formAddMenuList)) {
            LOG.warn("noCompanyNeed,consume:" + (DateTimeUtil.getInt() - start));
            return "noCompanyNeed";
        }
        LOG.warn("插入菜单");
        List<PaasMenuEntity> formMenuList = paasMenuModel.insertBatch(formAddMenuList);
        // 插入菜单对应的表单
        FormAddBatchDTO formAddBatchDTO = new FormAddBatchDTO();
        BeanUtil.copyProperties(fixDataJobDTO, formAddBatchDTO);
        List<FormEntityAddDTO> formList = new ArrayList<>();
        initJxcMenuHelp.getAccordConfigFormList(formList, formMenuList, AccordConfigMenuEnum.BATCH_FLOW_BILL);
        formAddBatchDTO.setFormList(formList);
        FormAddBatchVO formAddBatchVO = paasFormService.addBatch(formAddBatchDTO);
        if (Objects.isNull(formAddBatchVO)) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        MenuInitDTO menuInitDTO = new MenuInitDTO();
        BeanUtil.copyProperties(fixDataJobDTO, menuInitDTO);
        // 插入表单对应的字段解释
        initJxcMenuHelp.formExplainAddBatch(menuInitDTO, formAddBatchVO);
        if (CollectionsUtil.isNotEmpty(addConfigList)) {
            companyConfigModel.insertBatch(addConfigList);
        }
        if (CollectionsUtil.isNotEmpty(updateConfigList)) {
            companyConfigModel.updateBatch4Script(updateConfigList);
        }
        LOG.warn("插入流水公司数" + hasFlowCompanyList.size());
        for (int i = 0; i < hasFlowCompanyList.size(); i++) {
            String company = hasFlowCompanyList.get(i);
            BaseDTO baseDTO = new BaseDTO();
            baseDTO.setCorpid(company);
            LOG.warn("流水公司: " + (i + 1) + "/" + hasFlowCompanyList.size() + "/" + company);
            batchFlowBillService.insertMonthBeforeBatchFlowNoThread(baseDTO);
        }
        LOG.warn("consume:" + (DateTimeUtil.getInt() - start));
        LOG.warn("操作成功");
        return "success";
    }

    @RequestMapping(value = "/addProductExplain", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String addProductExplain(@RequestBody @Valid FixDataJobDTO fixDataJobDTO, BindingResult br) throws Exception {
        if (!proBaseConfig.getXbbCode().equals(fixDataJobDTO.getXbbCode())) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100006, SystemErrorCodeEnum.API_ERROR_100006.getMsg());
        }
        long start = DateTimeUtil.getInt();
        LocaleContextHolder.setLocale(Locale.CHINA);
        List<String> corpidList = fixDataJobDTO.getCorpidList();
        if (CollectionsUtil.isEmpty(corpidList)) {
            corpidList = companyModel.getCorpidList();
        }
        LOG.warn("数据库中共有公司" + corpidList.size() + "家");
        int corpidCount = 0;

        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put(ParameterConstant.DEL, DelEnum.NORMAL.getDel());
        param.put("configAlias", CompanyConfigEnum.ENABLE_BATCH_SHELF_MANAGEMENT.getAlias());
        param.put("corpidList", corpidList);
        param.put("noLimit", 1);
        param.put("columns", "corpid");
        param.put("configValue", "1");
        List<CompanyConfigEntity> batchConfigList = companyConfigModel.findEntitys(param);
        List<String> hasBatchConfigCompany = new ArrayList<>();
        batchConfigList.forEach(config -> {
            hasBatchConfigCompany.add(config.getCorpid());
        });
        List<FieldAttrEntity> fieldAttrList = new ArrayList<>();
        List<String> enumAttrs = InitExplainsHelper.getBusinessEnumAttrs(ProductEnum.class);
        List objs = Arrays.asList(ProductEnum.BATCH_SHELF_LIFE_MANAGEMENT, ProductEnum.ENABLE_BATCH_SHELF_LIFE, ProductEnum.SHELF_LIFE_DAYS, ProductEnum.EXPIRATION_ALERT_DAYS, ProductEnum.SERIAL_NUMBER_MANAGEMENT, ProductEnum.ENABLE_SERIAL_NUMBER);

        for (Object obj : objs) {
            FieldAttrEntity newFieldAttrEntity = InitExplainsHelper.setField(ProductEnum.class, enumAttrs, obj);
            try {
                Method method = TempProductEnum.class.getMethod("init" + newFieldAttrEntity.getSaasAttr().substring(0, 1).toUpperCase() + newFieldAttrEntity.getSaasAttr().substring(1), FieldAttrEntity.class);
                method.invoke(TempProductEnum.class, newFieldAttrEntity);

            } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
                e.printStackTrace();
            }
            newFieldAttrEntity.setIsRedundant(0);
            fieldAttrList.add(newFieldAttrEntity);
        }

        HashSet<String> attrList = new HashSet<>();
        for (FieldAttrEntity fieldAttrEntity : fieldAttrList) {
            attrList.add(fieldAttrEntity.getAttr());
        }
        for (String corpid : corpidList) {
            boolean hasBatch = hasBatchConfigCompany.contains(corpid);
            param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put(ParameterConstant.DEL, DelEnum.NORMAL.getDel());
            param.put(ParameterConstant.CORPID, corpid);
            param.put("businessType", XbbRefTypeEnum.PRODUCT.getCode());
            List<PaasFormExplainEntity> entitys = paasFormExplainModel.getNoHandleExplainsByFindEntitys(param);
            for (PaasFormExplainEntity entity : entitys) {
                if (Objects.equals("[]", entity.getExplains())) {
                    continue;
                }
                boolean canInsert = true;
                List<FieldAttrEntity> fieldAttrEntityList = JSONArray.parseArray(entity.getExplains(), FieldAttrEntity.class);

                int obj = 0;
                for (int i = 0; i < fieldAttrEntityList.size(); i++) {

                    FieldAttrEntity fieldAttrEntity = fieldAttrEntityList.get(i);
                    //插入到当前字段后面
                    if (Objects.equals(fieldAttrEntity.getAttr(), ProductEnum.SUPPLIER.getAttr())) {
                        obj = i + 1;
                    }
                    if (attrList.contains(fieldAttrEntity.getAttr())) {
                        canInsert = false;
                        LOG.warn(corpid + "该公司已经存在" + fieldAttrEntity.getAttr() + "字段");
                        break;
                    }

                }
                if (canInsert && obj != 0) {
                    for (int i = 0; i < fieldAttrList.size(); i++) {
                        FieldAttrEntity fieldAttrEntity = fieldAttrList.get(i);
                        if (hasBatch && (Objects.equals(fieldAttrEntity.getAttr(), ProductEnum.BATCH_SHELF_LIFE_MANAGEMENT.getAttr()) || Objects.equals(fieldAttrEntity.getAttr(), ProductEnum.ENABLE_BATCH_SHELF_LIFE.getAttr()) || Objects.equals(fieldAttrEntity.getAttr(), ProductEnum.SHELF_LIFE_DAYS.getAttr()) || Objects.equals(fieldAttrEntity.getAttr(), ProductEnum.EXPIRATION_ALERT_DAYS.getAttr()))) {
                            fieldAttrEntity.setVisible(1);
                            fieldAttrEntity.setEditHide(0);
                        } else {
                            fieldAttrEntity.setVisible(0);
                            fieldAttrEntity.setEditHide(1);
                        }
                        fieldAttrEntityList.add(obj + i, fieldAttrEntity);
                    }
                    String explains = JSONObject.toJSONString(fieldAttrEntityList);
                    entity.setExplains(explains);
                    paasFormExplainModel.update(entity);
                }
            }
            ++corpidCount;
            LOG.warn("公司" + corpidCount + "/" + corpidList.size() + "/" + corpid);
        }

        LOG.warn("consume:" + (DateTimeUtil.getInt() - start));
        LOG.warn("操作成功");
        return null;
    }

    @RequestMapping(value = "/addProductExplainPre", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String addProductExplainPre(@RequestBody @Valid FixDataJobDTO fixDataJobDTO, BindingResult br) throws Exception {
        if (!proBaseConfig.getXbbCode().equals(fixDataJobDTO.getXbbCode())) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100006, SystemErrorCodeEnum.API_ERROR_100006.getMsg());
        }
        LocaleContextHolder.setLocale(Locale.CHINA);
        long start = DateTimeUtil.getInt();
        List<String> corpidList = fixDataJobDTO.getCorpidList();
        if (CollectionsUtil.isEmpty(corpidList)) {
            corpidList = companyModel.getCorpidList();
        }
        LOG.warn("数据库中共有公司" + corpidList.size() + "家");
        int corpidCount = 0;
        List<FieldAttrEntity> fieldAttrList = new ArrayList<>();
        List<String> enumAttrs = InitExplainsHelper.getBusinessEnumAttrs(ProductEnum.class);
        List objs = Arrays.asList(ProductEnum.BATCH_SHELF_LIFE_MANAGEMENT, ProductEnum.ENABLE_BATCH_SHELF_LIFE, ProductEnum.SHELF_LIFE_DAYS, ProductEnum.EXPIRATION_ALERT_DAYS, ProductEnum.SERIAL_NUMBER_MANAGEMENT, ProductEnum.ENABLE_SERIAL_NUMBER);

        for (Object obj : objs) {
            FieldAttrEntity newFieldAttrEntity = InitExplainsHelper.setField(ProductEnum.class, enumAttrs, obj);
            try {
                Method method = TempProductEnum.class.getMethod("init" + newFieldAttrEntity.getSaasAttr().substring(0, 1).toUpperCase() + newFieldAttrEntity.getSaasAttr().substring(1), FieldAttrEntity.class);
                method.invoke(TempProductEnum.class, newFieldAttrEntity);

            } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
                e.printStackTrace();
            }
            newFieldAttrEntity.setIsRedundant(0);
            fieldAttrList.add(newFieldAttrEntity);
        }

        HashSet<String> attrList = new HashSet<>();
        for (FieldAttrEntity fieldAttrEntity : fieldAttrList) {
            attrList.add(fieldAttrEntity.getAttr());
        }
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put(ParameterConstant.DEL, DelEnum.NORMAL.getDel());
        param.put("businessType", XbbRefTypeEnum.PRODUCT.getCode());
        for (String corpid : corpidList) {
            param.put(ParameterConstant.CORPID, corpid);
            List<PaasFormExplainEntity> entitys = paasFormExplainModel.getNoHandleExplainsByFindEntitys(param);
            for (PaasFormExplainEntity entity : entitys) {
                if (Objects.equals("[]", entity.getExplains())) {
                    continue;
                }
                boolean canInsert = true;
                List<FieldAttrEntity> fieldAttrEntityList = JSONArray.parseArray(entity.getExplains(), FieldAttrEntity.class);

                int obj = 0;
                for (int i = 0; i < fieldAttrEntityList.size(); i++) {
                    FieldAttrEntity fieldAttrEntity = fieldAttrEntityList.get(i);
                    //插入到当前字段后面
                    if (Objects.equals(fieldAttrEntity.getAttr(), ProductEnum.SUPPLIER.getAttr())) {
                        obj = i + 1;
                    }
                    if (attrList.contains(fieldAttrEntity.getAttr())) {
                        canInsert = false;
                        LOG.warn(corpid + "该公司已经存在" + fieldAttrEntity.getAttr() + "字段");
                        break;
                    }
                }
                if (canInsert && obj != 0) {
                    fieldAttrEntityList.addAll(obj, fieldAttrList);
                    String explains = JSONObject.toJSONString(fieldAttrEntityList);
                    entity.setExplains(explains);
                    paasFormExplainModel.update(entity);
                }
            }
            ++corpidCount;
            LOG.warn("公司" + corpidCount + "/" + corpidList.size() + "/" + corpid);
        }

        LOG.warn("consume:" + (DateTimeUtil.getInt() - start));
        LOG.warn("操作成功");
        return null;
    }

    @RequestMapping(value = "/addProductExplainAfter", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String addProductExplainAfter(@RequestBody @Valid FixDataJobDTO fixDataJobDTO, BindingResult br) throws Exception {
        if (!proBaseConfig.getXbbCode().equals(fixDataJobDTO.getXbbCode())) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100006, SystemErrorCodeEnum.API_ERROR_100006.getMsg());
        }
        long start = DateTimeUtil.getInt();
        LocaleContextHolder.setLocale(Locale.CHINA);
        List<String> corpidList = fixDataJobDTO.getCorpidList();
        if (CollectionsUtil.isEmpty(corpidList)) {
            corpidList = companyModel.getCorpidList();
        }
        List<String> corpidExistBatch = productStockModel.getCorpidExistBatch(corpidList);
        LOG.warn("数据库中共有批次公司" + corpidExistBatch.size() + "家");
        int corpidCount = 0;
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put(ParameterConstant.DEL, DelEnum.NORMAL.getDel());
        param.put("businessType", XbbRefTypeEnum.PRODUCT.getCode());
        List<String> batchAttrList = Arrays.asList(ProductEnum.ENABLE_BATCH_SHELF_LIFE.getAttr(), ProductEnum.BATCH_SHELF_LIFE_MANAGEMENT.getAttr(), ProductEnum.SHELF_LIFE_DAYS.getAttr(), ProductEnum.EXPIRATION_ALERT_DAYS.getAttr());
        for (String corpid : corpidExistBatch) {
            param.put(ParameterConstant.CORPID, corpid);
            List<PaasFormExplainEntity> entitys = paasFormExplainModel.getNoHandleExplainsByFindEntitys(param);
            for (PaasFormExplainEntity entity : entitys) {
                if (Objects.equals("[]", entity.getExplains())) {
                    continue;
                }
                boolean canInsert = false;
                List<FieldAttrEntity> fieldAttrEntityList = JSONArray.parseArray(entity.getExplains(), FieldAttrEntity.class);
                for (int i = 0; i < fieldAttrEntityList.size(); i++) {
                    FieldAttrEntity fieldAttrEntity = fieldAttrEntityList.get(i);
                    if (batchAttrList.contains(fieldAttrEntity.getAttr())) {
                        fieldAttrEntity.setVisible(1);
                        fieldAttrEntity.setEditHide(0);
                        canInsert = true;
                    }
                }
                if (canInsert) {
                    String explains = JSONObject.toJSONString(fieldAttrEntityList);
                    entity.setExplains(explains);
                    paasFormExplainModel.update(entity);
                }
            }
            ++corpidCount;
            LOG.warn("公司" + corpidCount + "/" + corpidList.size() + "/" + corpid);
        }

        LOG.warn("consume:" + (DateTimeUtil.getInt() - start));
        LOG.warn("操作成功");
        return null;
    }

    /**
     * 老公司产品级配置批次保质期配置开关，序列号开关，只更新数据库，需同步es
     *
     * @param fixDataJobDTO 入参
     * @param br            校验
     * @return 成功
     * @throws Exception 异常
     */
    @RequestMapping(value = "/productIsEnableBatch", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String productIsEnableBatch(@RequestBody @Valid FixDataJobDTO fixDataJobDTO, BindingResult br) throws Exception {
        if (!proBaseConfig.getXbbCode().equals(fixDataJobDTO.getXbbCode())) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100006, SystemErrorCodeEnum.API_ERROR_100006.getMsg());
        }
        long start = DateTimeUtil.getInt();
        List<String> corpidList = fixDataJobDTO.getCorpidList();
        if (CollectionsUtil.isEmpty(corpidList)) {
            corpidList = productModel.getCorpidList();
        }
        LOG.warn("数据库中共有产品公司" + corpidList.size() + "家");
        int corpidCount = 0;
        for (String corpid : corpidList) {
            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put(ParameterConstant.DEL, DelEnum.NORMAL.getDel());
            param.put(ParameterConstant.CORPID, corpid);
            param.put("columns", "id, `data`->\"$.num_3\" as parentId");
            param.put("orderByStr", "id");
            param.put("pageSize", 2000);
            boolean flag = true;
            while (flag) {
                List<ProductEntityExt> productEntityExtList = productModel.findEntitys(param);
                if (Objects.isNull(productEntityExtList) || productEntityExtList.isEmpty()) {
                    flag = false;
                } else {
                    LOG.warn("遍历id到" + productEntityExtList.get(productEntityExtList.size() - 1).getId());
                    param.put("idGte", productEntityExtList.get(productEntityExtList.size() - 1).getId());
                    Set<Long> parentIdSet = new HashSet<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                    for (ProductEntityExt productEntityExt : productEntityExtList) {
                        if (Objects.nonNull(productEntityExt.getParentId())) {
                            if (!Objects.equals(productEntityExt.getParentId(), 0L)) {
                                parentIdSet.add(productEntityExt.getParentId());
                            } else {
                                parentIdSet.add(productEntityExt.getId());
                            }
                        }
                    }
                    List<ProductStockEntity> existBatchEntityList = productStockModel.getExistBatchEntity(corpid, parentIdSet);
                    Set<Long> hasBatchSet = new HashSet<>();
                    Set<Long> hasGuaranteePeriodSet = new HashSet<>();
                    for (ProductStockEntity stockEntity : existBatchEntityList) {
                        hasBatchSet.add(stockEntity.getParentId());
                        if (stockEntity.getProduceDate() > 0) {
                            hasGuaranteePeriodSet.add(stockEntity.getParentId());
                        }
                    }
                    List<UpdateDataEntity> updateList = new ArrayList<>();
                    JSONObject updateData;
                    for (ProductEntityExt productEntityExt : productEntityExtList) {
                        if (Objects.nonNull(productEntityExt.getParentId())) {
                            updateData = new JSONObject();
                            Long parentId = productEntityExt.getParentId();
                            if (parentId == 0L) {
                                parentId = productEntityExt.getId();
                            }
                            updateData.put(ProductEnum.ENABLE_SERIAL_NUMBER.getAttr(), 0);
                            if (hasGuaranteePeriodSet.contains(parentId)) {
                                updateData.put(ProductEnum.SHELF_LIFE_DAYS.getAttr(), 0);
                            }
                            if (hasBatchSet.contains(parentId)) {
                                updateData.put(ProductEnum.ENABLE_BATCH_SHELF_LIFE.getAttr(), 1);
                            } else {
                                updateData.put(ProductEnum.ENABLE_BATCH_SHELF_LIFE.getAttr(), 0);
                            }
                            updateList.add(ExplainUtil.getUpdateData(productEntityExt.getId(), updateData, corpid));
                        }
                    }
                    productModel.updateBatch4JobNoEs(updateList, corpid);
                }
            }
            ++corpidCount;
            LOG.warn("公司" + corpidCount + "/" + corpidList.size());
        }
        LOG.warn("consume:" + (DateTimeUtil.getInt() - start));
        LOG.warn("操作成功");
        return "success";
    }

    /**
     * 增加到期日期字段
     *
     * @param fixDataJobDTO
     * @param br
     * @return
     * @throws Exception
     */

    @RequestMapping(value = "/addExpireDateExplain", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String addExpireDateExplain(@RequestBody @Valid FixDataJobDTO fixDataJobDTO, BindingResult br) throws Exception {
        if (!proBaseConfig.getXbbCode().equals(fixDataJobDTO.getXbbCode())) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100006, SystemErrorCodeEnum.API_ERROR_100006.getMsg());
        }
        long start = DateTimeUtil.getInt();
        LocaleContextHolder.setLocale(Locale.CHINA);
        List<String> corpidList = fixDataJobDTO.getCorpidList();
        if (CollectionsUtil.isEmpty(corpidList)) {
            corpidList = companyModel.getCorpidList();
        }
        LOG.warn("数据库中共有产品公司" + corpidList.size() + "家");
        int corpidCount = 0;
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put(ParameterConstant.DEL, DelEnum.NORMAL.getDel());
        param.put("configAlias", CompanyConfigEnum.ENABLE_BATCH_SHELF_MANAGEMENT.getAlias());
        param.put("corpidList", corpidList);
        param.put("noLimit", 1);
        param.put("columns", "corpid");
        param.put("configValue", "1");
        List<CompanyConfigEntity> batchConfigList = companyConfigModel.findEntitys(param);
        List<String> hasBatchConfigCompany = new ArrayList<>();
        batchConfigList.forEach(config -> {
            hasBatchConfigCompany.add(config.getCorpid());
        });
        List<Integer> businessTypeList = Arrays.asList(XbbRefTypeEnum.OTHER_INSTOCK.getCode(), XbbRefTypeEnum.PURCHASE_INSTOCK.getCode(), XbbRefTypeEnum.PRODUCTION_INSTOCK.getCode(), XbbRefTypeEnum.RETURNED_MATERIEL_INSTOCK.getCode(), XbbRefTypeEnum.OTHER_OUTSTOCK.getCode(), XbbRefTypeEnum.WORK_ORDER_OUTSTOCK.getCode(), XbbRefTypeEnum.PRODUCTION_MATERIEL_OUTSTOCK.getCode(), XbbRefTypeEnum.RETURNED_PURCHASE_OUTSTOCK.getCode(), XbbRefTypeEnum.CONTRACT_OUTSTOCK.getCode(), XbbRefTypeEnum.ASSEMBLE.getCode());

        Map<Integer, FieldAttrEntity> map = new HashMap<>();

        for (Integer businessType : businessTypeList) {
            FieldAttrEntity fieldAttrEntity = new FieldAttrEntity();
            if (Objects.equals(businessType, XbbRefTypeEnum.OTHER_INSTOCK.getCode())) {
                fieldAttrEntity = addSaasExplain(InstockProductEnum.class, TempInstockProductEnum.class);
            } else if (Objects.equals(businessType, XbbRefTypeEnum.PURCHASE_INSTOCK.getCode())) {
                fieldAttrEntity = addSaasExplain(PurchaseInstockProductEnum.class, TempPurchaseInstockProductEnum.class);
            } else if (Objects.equals(businessType, XbbRefTypeEnum.PRODUCTION_INSTOCK.getCode())) {
                fieldAttrEntity = addSaasExplain(ProductionInstockProductEnum.class, TempProductionInstockProductEnum.class);
            } else if (Objects.equals(businessType, XbbRefTypeEnum.RETURNED_MATERIEL_INSTOCK.getCode())) {
                fieldAttrEntity = addSaasExplain(ReturnedMaterielInstockProductEnum.class, TempReturnedMaterielInstockProductEnum.class);
            } else if (Objects.equals(businessType, XbbRefTypeEnum.OTHER_OUTSTOCK.getCode())) {
                fieldAttrEntity = addSaasExplain(OutstockProductEnum.class, TempOutstockProductEnum.class);
            } else if (Objects.equals(businessType, XbbRefTypeEnum.WORK_ORDER_OUTSTOCK.getCode())) {
                fieldAttrEntity = addSaasExplain(WorkOrderOutstockProductEnum.class, TempWorkOrderOutstockProductEnum.class);
            } else if (Objects.equals(businessType, XbbRefTypeEnum.PRODUCTION_MATERIEL_OUTSTOCK.getCode())) {
                fieldAttrEntity = addSaasExplain(ProductionMaterielOutstockProductEnum.class, TempProductionMaterielOutstockProductEnum.class);
            } else if (Objects.equals(businessType, XbbRefTypeEnum.RETURNED_PURCHASE_OUTSTOCK.getCode())) {
                fieldAttrEntity = addSaasExplain(ReturnedPurchaseOutstockProductEnum.class, TempReturnedPurchaseOutstockProductEnum.class);
            } else if (Objects.equals(businessType, XbbRefTypeEnum.CONTRACT_OUTSTOCK.getCode())) {
                fieldAttrEntity = addSaasExplain(ContractOutstockProductEnum.class, TempContractOutstockProductEnum.class);
            }
            map.put(businessType, fieldAttrEntity);
        }

        FieldAttrEntity assembleInProductEntity = addSaasExplain(AssembleInProductEnum.class, TempAssembleInProductEnum.class);
        FieldAttrEntity assembleOutProductEntity = addSaasExplain(AssembleProductEnum.class, TempAssembleProductEnum.class);

        FieldAttrEntity oriProductEntity = addSaasExplain(OriStockProductEnum.class, TempOriStockProductEnum.class);
        PaasFormExplainEntity oriExplain = paasFormExplainModel.getSystemDefaultExplain(XbbRefTypeEnum.ORI_STOCK.getCode());
        List<FieldAttrEntity> oriFieldAttrEntityList = JSONArray.parseArray(oriExplain.getExplains(), FieldAttrEntity.class);
        int oriObj = 0;
        boolean oriCanInsert = true;
        for (int i = 0; i < oriFieldAttrEntityList.size(); i++) {

            FieldAttrEntity fieldAttrEntity = oriFieldAttrEntityList.get(i);
            if (Objects.equals(fieldAttrEntity.getFieldType(), FieldTypeEnum.SELECT_PRODUCT.getType())) {
                List<FieldAttrEntity> subExplainList = (List<FieldAttrEntity>) fieldAttrEntity.getSubForm().getItems();
                for (int i1 = 0; i1 < subExplainList.size(); i1++) {
                    FieldAttrEntity attrEntity = subExplainList.get(i1);
                    //插入到当前字段后面
                    if (Objects.equals(attrEntity.getAttr(), SelectProductEnum.GUARANTEE_PERIOD.getAttr())) {
                        oriObj = i1 + 1;
                    }
                    if (Objects.equals(attrEntity.getAttr(), SelectProductEnum.EXPIRE_DATE.getAttr())) {
                        oriCanInsert = false;
                    }
                }
                if (oriCanInsert && oriObj != 0) {
                    oriProductEntity.setIsForbidden(0);
                    oriProductEntity.setParentAttr(OriStockEnum.PRODUCT_DETAIL.getAttr());
                    subExplainList.add(oriObj, oriProductEntity);
                    fieldAttrEntity.getSubForm().setItems(subExplainList);
                    oriExplain.setExplains(JSONObject.toJSONString(oriFieldAttrEntityList));
                    paasFormExplainModel.update(oriExplain);
                }
            }
        }
        for (String corpid : corpidList) {
            boolean batchShelf = hasBatchConfigCompany.contains(corpid);
            param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put(ParameterConstant.DEL, DelEnum.NORMAL.getDel());
            param.put(ParameterConstant.CORPID, corpid);

            for (Integer businessType : businessTypeList) {
                param.put("businessType", businessType);
                List<PaasFormExplainEntity> entitys = paasFormExplainModel.getNoHandleExplainsByFindEntitys(param);
                for (PaasFormExplainEntity entity : entitys) {
                    if (Objects.equals("[]", entity.getExplains())) {
                        continue;
                    }
                    boolean canInsert = true;
                    List<FieldAttrEntity> fieldAttrEntityList = JSONArray.parseArray(entity.getExplains(), FieldAttrEntity.class);
                    String parentAttr = "";
                    int obj = 0;

                    for (int i = 0; i < fieldAttrEntityList.size(); i++) {

                        FieldAttrEntity fieldAttrEntity = fieldAttrEntityList.get(i);
                        if (Objects.equals(fieldAttrEntity.getFieldType(), FieldTypeEnum.SELECT_PRODUCT.getType())) {

                            if (Objects.isNull(fieldAttrEntity.getSubForm()) || Objects.isNull(fieldAttrEntity.getSubForm().getItems())) {
                                LOG.warn("关联产品没有subForm的corpid:" + entity.getCorpid() + "/解释id:" + entity.getId() + "/formId:" + entity.getFormId());
                                continue;
                            }
                            parentAttr = fieldAttrEntity.getAttr();
                            List<FieldAttrEntity> subExplainList = (List<FieldAttrEntity>) fieldAttrEntity.getSubForm().getItems();
                            for (int i1 = 0; i1 < subExplainList.size(); i1++) {
                                FieldAttrEntity attrEntity = subExplainList.get(i1);
                                //插入到当前字段后面
                                if (Objects.equals(attrEntity.getAttr(), SelectProductEnum.GUARANTEE_PERIOD.getAttr())) {
                                    obj = i1 + 1;
                                }
                                if (!batchShelf && (Objects.equals(attrEntity.getAttr(), SelectProductEnum.GUARANTEE_PERIOD.getAttr()) || Objects.equals(attrEntity.getAttr(), SelectProductEnum.BATCH.getAttr()) || Objects.equals(attrEntity.getAttr(), SelectProductEnum.PRODUCE_DATE.getAttr()))) {
                                    attrEntity.setVisible(0);
                                    attrEntity.setEditHide(1);
                                }
                                if (Objects.equals(attrEntity.getAttr(), SelectProductEnum.EXPIRE_DATE.getAttr())) {
                                    canInsert = false;
                                    LOG.warn(corpid + "该公司" + businessType + "已经存在" + attrEntity.getAttr() + "字段");
                                    break;
                                }
                            }


                            if (canInsert && obj != 0) {
                                FieldAttrEntity fieldAttrEntity1;
                                if (!Objects.equals(businessType, XbbRefTypeEnum.ASSEMBLE.getCode())) {
                                    fieldAttrEntity1 = map.get(businessType);
                                } else if (Objects.equals(fieldAttrEntity.getAttr(), AssembleEnum.OUT_PRODUCTS.getAttr())) {
                                    fieldAttrEntity1 = assembleOutProductEntity;
                                } else {
                                    fieldAttrEntity1 = assembleInProductEntity;
                                }
                                fieldAttrEntity1.setIsForbidden(0);
                                if (batchShelf) {
                                    fieldAttrEntity1.setVisible(1);
                                    fieldAttrEntity1.setEditHide(0);
                                } else {
                                    fieldAttrEntity1.setVisible(0);
                                    fieldAttrEntity1.setEditHide(1);
                                }
                                fieldAttrEntity1.setParentAttr(parentAttr);
                                subExplainList.add(obj, fieldAttrEntity1);

                                fieldAttrEntity.getSubForm().setItems(subExplainList);
                                String explains = JSONObject.toJSONString(fieldAttrEntityList);
                                entity.setExplains(explains);
                                paasFormExplainModel.update(entity);
                            }

                            if (!Objects.equals(businessType, XbbRefTypeEnum.ASSEMBLE.getCode())) {
                                break;
                            }
                        }
                    }
                }
            }

            ++corpidCount;
            LOG.warn("公司" + corpidCount + "/" + corpidList.size());
        }

        LOG.warn("consume:" + (DateTimeUtil.getInt() - start));
        LOG.warn("操作成功");
        return null;
    }

    private FieldAttrEntity addSaasExplain(Class<?> clazz, Class<?> tempClazz) throws XbbException {

        List<String> enumAttrs = InitExplainsHelper.getBusinessEnumAttrs(clazz);
        Object o = new Object();
        Object[] objs = clazz.getEnumConstants();
        for (Object obj : objs) {
            try {
                String name = (String) clazz.getMethod("getAttr").invoke(obj);
                if (Objects.equals(name, "num_40")) {
                    o = obj;
                    break;
                }
            } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
                e.printStackTrace();
            }

        }
        FieldAttrEntity newFieldAttrEntity = InitExplainsHelper.setField(clazz, enumAttrs, o);
        try {
            Method method = tempClazz.getMethod("init" + newFieldAttrEntity.getSaasAttr().substring(0, 1).toUpperCase() + newFieldAttrEntity.getSaasAttr().substring(1), FieldAttrEntity.class);
            method.invoke(tempClazz, newFieldAttrEntity);

        } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
            e.printStackTrace();
        }
        newFieldAttrEntity.setIsRedundant(0);

        return newFieldAttrEntity;

    }

}
